package org.smartercontext.contextmger.utilities;

import java.util.ArrayList;
import java.util.List;

import org.smartercontext.contextmger.DTO.BooksDTO;
import org.smartercontext.contextmger.DTO.MovieDTO;
import org.smartercontext.contextmger.DTO.MusicDTO;
import org.smartercontext.contextmger.contextsphere.ContextManagerController;

import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;

public class GetMMB {

	private List<MusicDTO>musicPrefs;
	private List<MovieDTO>moviesPrefs;
	private List<BooksDTO>booksPrefs;
	
	public GetMMB(){
		
	}
	
	public Model deleteMMBToUserModel(Model usermodel, String username, List<String>toDelete){
		
		String nsUser="http://smartercontext.org/vocabularies/rdf/"+username+".rdf#";
		Resource resource = usermodel.getResource(nsUser+username);
		
		for(int i=0;i<toDelete.size();i++){
			StmtIterator iterator = resource.listProperties();
			
			boolean find1 = false;
			List<Statement>stmts = new ArrayList<>();
			while(iterator.hasNext()){
				Statement stmt = iterator.next();
				if(stmt.getObject().toString().equals(nsUser+toDelete.get(i))){
					find1 = true;
				}else{
					
					stmts.add(stmt);
				}
			}
			
			if(find1){
				
				Resource preference = usermodel.getResource(nsUser+toDelete.get(i));
				usermodel.remove(resource.listProperties());
				usermodel.remove(preference.listProperties());
				usermodel.add(stmts);
			}
			
		}
		
		
		return usermodel;
	}
	
	public Model modifyMMBToUserModel(Model usermodel, String username){
		
		String nsUser="http://smartercontext.org/vocabularies/rdf/"+username+".rdf#";
		Resource resource = usermodel.getResource(nsUser+username);
		OntModel modelPrefs = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_MICRO_RULE_INF);
		DatatypeProperty artifCat = modelPrefs.createDatatypeProperty(ContextManagerController.getNsSchemaGC()+"artificialCategory");
		Property likes = modelPrefs.createProperty(ContextManagerController.getNsSchemaPERSONAL()+"likes");
		Property rdfType = usermodel.createProperty(ContextManagerController.getRdf(),"type");
		Property artifEn = usermodel.createProperty(ContextManagerController.getNsSchemaGC()+"ArtificialEntity");
		
		for(int i=0;i<booksPrefs.size();i++){
			
			BooksDTO temp = booksPrefs.get(i);
			String oldname = temp.getOldName();
			String newname = temp.getName();
			
			
			StmtIterator iterator = resource.listProperties(likes);
			List<Statement>stmts = new ArrayList<>();
			boolean find = false;
			
			while(iterator.hasNext()){
				Statement stmt = iterator.next();
				String object = stmt.getObject().toString();
				
				if(object.equals(nsUser+oldname)){
					find=true;
				}else{
					stmts.add(stmt);
				}
			}
			
			if(find){
				
				Resource pref = usermodel.getResource(nsUser+oldname);
				Literal type = usermodel.createTypedLiteral(new String("Books"));
				
				if(newname == null){
					
					usermodel.remove(pref.listProperties(artifCat));
					usermodel.addLiteral(pref, artifCat, type);
					
				}else{
					
					Resource prefNew = usermodel.createResource(nsUser+newname);
					usermodel.add(prefNew, rdfType, artifEn);
					
					usermodel.remove(resource.listProperties(likes));
					usermodel.add(stmts);
					usermodel.add(resource,likes,prefNew);
					usermodel.remove(pref.listProperties());
					usermodel.addLiteral(prefNew, artifCat, type);
				}
			}
		}
		
		for(int i=0;i<moviesPrefs.size();i++){
			
			MovieDTO temp = moviesPrefs.get(i);
			String oldname = temp.getOldName();
			String newname = temp.getName();
			
			
			StmtIterator iterator = resource.listProperties(likes);
			List<Statement>stmts = new ArrayList<>();
			boolean find = true;
			
			while(iterator.hasNext()){
				Statement stmt = iterator.next();
				String object = stmt.getObject().toString();
				
				if(object.equals(nsUser+oldname)){
					find=true;
				}else{
					stmts.add(stmt);
				}
			}
			
			if(find){
				
				Resource pref = usermodel.getResource(nsUser+oldname);
				Literal type = modelPrefs.createTypedLiteral(new String("Movies"));
				
				if(newname == null){
					
					usermodel.remove(pref.listProperties(artifCat));
					usermodel.addLiteral(pref, artifCat, type);
					
				}else{
					
					Resource prefNew = usermodel.createResource(nsUser+newname);
					usermodel.add(prefNew, rdfType, artifEn);
					
					usermodel.remove(resource.listProperties(likes));
					usermodel.add(stmts);
					usermodel.add(resource,likes,prefNew);
					usermodel.remove(pref.listProperties());
					usermodel.addLiteral(prefNew, artifCat, type);
				}
			}
		}
		
		for(int i=0;i<musicPrefs.size();i++){
			
			MusicDTO temp = musicPrefs.get(i);
			String oldname = temp.getOldName();
			String newname = temp.getName();
			
			
			StmtIterator iterator = resource.listProperties(likes);
			List<Statement>stmts = new ArrayList<>();
			boolean find = true;
			
			while(iterator.hasNext()){
				Statement stmt = iterator.next();
				String object = stmt.getObject().toString();
				
				if(object.equals(nsUser+oldname)){
					
					find=true;
				}else{
					stmts.add(stmt);
				}
			}
			
			if(find){
				
				Resource pref = usermodel.getResource(nsUser+oldname);
				Literal type = usermodel.createTypedLiteral(new String("Music"));
				
				if(newname == null){
					
					usermodel.remove(pref.listProperties(artifCat));
					usermodel.addLiteral(pref, artifCat, type);
					
				}else{
					
					Resource prefNew = usermodel.createResource(nsUser+newname);
					usermodel.add(prefNew, rdfType, artifEn);
					
					usermodel.remove(resource.listProperties(likes));
					usermodel.add(stmts);
					usermodel.add(resource,likes,prefNew);
					usermodel.remove(pref.listProperties());
					usermodel.addLiteral(prefNew, artifCat, type);
				}
			}
		}
		
		return usermodel;
	}
	
	public Model addMMBToUserModel(Model usermodel, String username){
		
		String nsUser="http://smartercontext.org/vocabularies/rdf/"+username+".rdf#";
		Resource resource = usermodel.getResource(nsUser+username);
		
		
		Property rdfType = usermodel.createProperty(ContextManagerController.getRdf(),"type");
		Property movieType = usermodel.createProperty(ContextManagerController.getNsSchemaGC()+"ArtificialEntity");
		OntModel modelPrefs = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_MICRO_RULE_INF);
		DatatypeProperty artifCat = modelPrefs.createDatatypeProperty(ContextManagerController.getNsSchemaGC()+"artificialCategory");
		Property likes = modelPrefs.createProperty(ContextManagerController.getNsSchemaPERSONAL()+"likes");
		Literal artifCatL;
		
		for(int i=0;i<musicPrefs.size();i++){
			MusicDTO temp = musicPrefs.get(i);
			String name = temp.getName();
			Resource music = usermodel.createResource(nsUser+name);
			usermodel.add(music, rdfType, movieType);
			
			artifCatL = modelPrefs.createTypedLiteral(new String("Music"));
			usermodel.addLiteral(music, artifCat, artifCatL);
			
			resource.addProperty(likes, music);
			
		}
		
		for(int i=0;i<moviesPrefs.size();i++){
			MovieDTO temp = moviesPrefs.get(i);
			String name = temp.getName();
			Resource movie = usermodel.createResource(nsUser+name);
			usermodel.add(movie,rdfType,movieType);
			
			artifCatL = modelPrefs.createTypedLiteral(new String("Movies"));
			usermodel.addLiteral(movie, artifCat, artifCatL);
			
			resource.addProperty(likes, movie);
		}
		
		for(int i=0;i<booksPrefs.size();i++){
			BooksDTO temp = booksPrefs.get(i);
			String name = temp.getName();
			Resource book = usermodel.createResource(nsUser+name);
			usermodel.add(book,rdfType,movieType);
			
			artifCatL = modelPrefs.createTypedLiteral(new String("Books"));
			usermodel.addLiteral(book, artifCat, artifCatL);
			
			resource.addProperty(likes, book);
		}
		
		return usermodel;
	}
	
	
	public void getMMB(Model usermodel, String username){
		
		String nsUser="http://smartercontext.org/vocabularies/rdf/"+username+".rdf#";
		Resource resource = usermodel.getResource(nsUser+username);
		
		Property likeAs = usermodel.createProperty(ContextManagerController.getNsSchemaPERSONAL()+"likes");
		Property artifCat = usermodel.createProperty(ContextManagerController.getNsSchemaGC()+"artificialCategory");
		
		musicPrefs = new ArrayList<>();
		moviesPrefs = new ArrayList<>();
		booksPrefs = new ArrayList<>();
		
		StmtIterator iterator = resource.listProperties(likeAs);
		while(iterator.hasNext()){
			Statement stmt = iterator.next();
			String object = stmt.getObject().toString();
			Resource artifcialE = usermodel.getResource(object);
			Statement stmt1 = artifcialE.getProperty(artifCat);
			if(stmt1!=null){
				String cat = stmt1.getObject().asLiteral().getString();
				
				if(cat.equals("Music")){
					MusicDTO mdto = new MusicDTO();
					mdto.setCategory("Music");
					mdto.setName(object.split("#")[1]);
					musicPrefs.add(mdto);
				}else if(cat.equals("Movies")){
					MovieDTO mdto = new MovieDTO();
					mdto.setCategory("Movies");
					mdto.setName(object.split("#")[1]);
					moviesPrefs.add(mdto);
				}else if(cat.equals("Books")){
					BooksDTO bdto = new BooksDTO();
					bdto.setCategory("Books");
					bdto.setName(object.split("#")[1]);
					booksPrefs.add(bdto);
				}
			}
		}
	}

	public List<MusicDTO> getMusicPrefs() {
		return musicPrefs;
	}

	public void setMusicPrefs(List<MusicDTO> musicPrefs) {
		this.musicPrefs = musicPrefs;
	}

	public List<MovieDTO> getMoviesPrefs() {
		return moviesPrefs;
	}

	public void setMoviesPrefs(List<MovieDTO> moviesPrefs) {
		this.moviesPrefs = moviesPrefs;
	}

	public List<BooksDTO> getBooksPrefs() {
		return booksPrefs;
	}

	public void setBooksPrefs(List<BooksDTO> booksPrefs) {
		this.booksPrefs = booksPrefs;
	}
	
	
}
